package repository

import (
	"context"
	"github.com/wuzfei/go-helper/time"
	"gorm.io/gorm"
	"onvif_server/internal/model"
	time2 "time"
)

type AlarmQueryFilter struct {
	Status    int         `json:"status"`
	EventType int         `json:"event_type"`
	DeviceId  []string    `json:"device_id"`
	DateRange *time.Range `json:"date_range"`
}

type AlarmRepository interface {
	List(ctx context.Context, filter *AlarmQueryFilter, scopesFn ...func(*gorm.DB) *gorm.DB) (total int64, res []*model.Alarm, err error)
	Create(ctx context.Context, m *model.Alarm) error
	Update(ctx context.Context, m *model.Alarm, fields ...string) error
	GetById(ctx context.Context, id int) (*model.Alarm, error)
	BatchProcessStatus(ctx context.Context, status int, remark string) error
	DeleteByIDs(ctx context.Context, ids []int) error
	DeleteBeforeTime(ctx context.Context, t time2.Time) error
}

func NewAlarmRepository(r *Repository) AlarmRepository {
	return &alarmRepository{
		Repository: r,
	}
}

type alarmRepository struct {
	*Repository
}

// List 获取列表
func (r *alarmRepository) List(ctx context.Context, filter *AlarmQueryFilter, scopesFn ...func(*gorm.DB) *gorm.DB) (total int64, res []*model.Alarm, err error) {
	db := r.DB(ctx).Model(&model.Alarm{})
	if filter.Status > 0 {
		db.Where("status = ?", filter.Status)
	}
	if filter.EventType > 0 {
		db.Where("event_type = ?", filter.EventType)
	}
	if len(filter.DeviceId) > 0 {
		if len(filter.DeviceId) == 1 {
			db.Where("device_id = ?", filter.DeviceId[0])
		} else {
			db.Where("device_id in ?", filter.DeviceId)
		}
	}
	if filter.DateRange != nil {
		db.Where("created_at >= ? and created_at <= ?", filter.DateRange.StartTime, filter.DateRange.EndTime)
	}
	err = db.Count(&total).Error
	if err != nil || total == 0 {
		return
	}
	err = db.Scopes(scopesFn...).Preload("Camera").Order("created_at desc").Find(&res).Error
	return
}

func (r *alarmRepository) Create(ctx context.Context, m *model.Alarm) error {
	return r.DB(ctx).Create(m).Error
}

func (r *alarmRepository) Update(ctx context.Context, m *model.Alarm, fields ...string) error {
	_db := r.DB(ctx)
	if len(fields) > 0 {
		_db = _db.Select(fields)
	}
	return _db.Where("id = ?", m.ID).Updates(m).Error
}

func (r *alarmRepository) BatchProcessStatus(ctx context.Context, status int, remark string) error {
	return r.DB(ctx).Model(&model.Alarm{}).Where("status = ?", model.AlarmStatusNormal).Updates(map[string]any{
		"status": status,
		"remark": remark,
	}).Error
}

func (r *alarmRepository) GetById(ctx context.Context, id int) (m *model.Alarm, err error) {
	err = r.DB(ctx).Model(&model.Alarm{}).Where("id = ?", id).Preload("Camera").First(&m).Error
	return
}

func (r *alarmRepository) DeleteByIDs(ctx context.Context, ids []int) error {
	return r.DB(ctx).Delete(&model.Alarm{}, ids).Error
}

func (r *alarmRepository) DeleteBeforeTime(ctx context.Context, t time2.Time) error {
	return r.DB(ctx).Where("created_at <= ?", t).Delete(&model.Alarm{}).Error
}
